import pandas as pd
import pyecharts as echart
import numpy as np
import os

from typing import Dict
from pyecharts.charts import Bar, Line, Tab
from pyecharts.commons.utils import JsCode

def read_excel_datas():
    data_dir = "./data"
    excel_sheet_name = [
        "总览表", "本科就业去向(单位性质)", 
        "硕士就业去向(单位性质)", "博士就业去向(单位性质)",
        "本科升学去向", "硕士升学去向", "就业观念"
    ]

    excel_file_names = os.listdir(data_dir)
    excel_datas = dict()
    for excel_file_name in excel_file_names:
        excel_data = pd.read_excel(data_dir + "/" + excel_file_name, sheet_name=excel_sheet_name)
        data_name = excel_file_name.split(".")[0]
        excel_datas[data_name] = excel_data
    
    return excel_datas

def render_total(school: str, data: pd.DataFrame):
    rate_college = "本科升学率"
    years = [] 
    for year in data["年份"].to_numpy():
        years.append(str(year))
    
    (
        Line()
        .add_xaxis(years)
        .add_yaxis(series_name=rate_college, y_axis=data[rate_college].to_numpy())
        .set_global_opts(title_opts=echart.options.TitleOpts(title=school))
        .render(school + ".html")
    )

def render_employment(school: str, level: str, data: pd.DataFrame) -> Line:
    years = [] 
    for year in data["年份"].to_numpy():
        years.append(str(year))
    
    chart = (
        Line()
        .add_xaxis(years)
        .set_global_opts(
            title_opts=echart.options.TitleOpts(title=level + "就业调查"),
            yaxis_opts=echart.options.AxisOpts(axislabel_opts=echart.options.LabelOpts(formatter="{value} %"))
        )
    )

    headers = ["党政机关", "事业单位", "民营企业", "国有企业", "灵活就业", "创业", "其他"]
    for header in headers:
        chart.add_yaxis(series_name=header, y_axis=data[header+"%"].to_numpy() * 100, 
        label_opts=echart.options.LabelOpts(formatter=JsCode("function (params) {return params.value[1].toFixed(1) + '%'}")))
    
    return chart

def render_upgrade(school: str, level: str, data: pd.DataFrame) -> Line:
    years = [] 
    for year in data["年份"].to_numpy():
        years.append(str(year))
    
    chart = (
        Line()
        .add_xaxis(years)
        .set_global_opts(
            title_opts=echart.options.TitleOpts(title=level + "升学去向调查"),
            yaxis_opts=echart.options.AxisOpts(axislabel_opts=echart.options.LabelOpts(formatter="{value} %"))
        )
    )

    headers = ["中国大陆", "英国", "中国香港"]
    for header in headers:
        chart.add_yaxis(series_name=header, y_axis=data[header+"%"].to_numpy() * 100, 
        label_opts=echart.options.LabelOpts(formatter=JsCode("function (params) {return params.value[1].toFixed(1) + '%'}")))
    
    return chart

def render_compare_employment(school: str, data: Dict[str, pd.DataFrame], entry: str) -> Bar:
    years = ["2018", "2019", "2020", "2021"]
    levels = ["本科", "硕士", "博士"]

    chart = (
        Bar()
        .add_xaxis(years)
        .set_global_opts(
            title_opts=echart.options.TitleOpts(title="毕业生赴" + entry + "就业对比图"),
            yaxis_opts=echart.options.AxisOpts(axislabel_opts=echart.options.LabelOpts(formatter="{value} %"))
        )
    )

    for level in levels:
        sheet_name = level + "就业去向(单位性质)";
        # bug -> 这里没办法用 np.ndarray
        list_data = []
        for rate in data[sheet_name][entry+"%"].to_numpy() * 100:
            list_data.append(round(rate, 1))
        chart.add_yaxis(level, list_data)

    return chart

def render_compare_upgrade(school: str, data: Dict[str, pd.DataFrame], entry: str) -> Bar:
    years = ["2018", "2019", "2020", "2021"]
    levels = ["本科", "硕士"]

    chart = (
        Bar()
        .add_xaxis(years)
        .set_global_opts(
            title_opts=echart.options.TitleOpts(title="毕业生赴" + entry + "深造对比图"),
            yaxis_opts=echart.options.AxisOpts(axislabel_opts=echart.options.LabelOpts(formatter="{value} %"))
        )
    )

    for level in levels:
        sheet_name = level + "升学去向";
        # bug -> 这里没办法用 np.ndarray
        list_data = []
        for rate in data[sheet_name][entry+"%"].to_numpy() * 100:
            list_data.append(round(rate, 1))
        chart.add_yaxis(level, list_data)

    return chart

def render_charts(excel_datas: Dict[str, pd.DataFrame]):
    for (school, data) in excel_datas.items():
        charts = Tab()

        college_employment_line = render_employment(school, "本科", data["本科就业去向(单位性质)"])
        charts.add(college_employment_line, "本科就业去向调查")
        master_employment_line = render_employment(school, "硕士", data["硕士就业去向(单位性质)"])
        charts.add(master_employment_line, "硕士就业去向调查")
        doctor_employment_line = render_employment(school, "博士", data["博士就业去向(单位性质)"])
        charts.add(doctor_employment_line, "博士就业去向调查")

        college_employment_line = render_upgrade(school, "本科", data["本科升学去向"])
        charts.add(college_employment_line, "本科升学去向调查")
        master_employment_line = render_upgrade(school, "硕士", data["硕士升学去向"])
        charts.add(master_employment_line, "硕士升学去向调查")

        headers = ["党政机关", "事业单位", "民营企业", "国有企业", "灵活就业", "创业", "其他"]

        for header in headers:
            compare = render_compare_employment(school, data, header)
            charts.add(compare, "毕业生赴" + header + "就业对比图")

        headers = ["中国大陆", "英国", "中国香港"]

        for header in headers:
            compare = render_compare_upgrade(school, data, header)
            charts.add(compare, "毕业生赴" + header + "深造对比图")

        charts.render("./charts/" + school + ".html")

if __name__ == "__main__":
    datas = read_excel_datas()
    render_charts(datas)